#pragma once
#ifndef VIEWCAMERA_H
#define VIEWCAMERA_H

#include <QVector3D>
#include <QMatrix4x4>
#include <QQuaternion>
#include <QMouseEvent>

constexpr float global_near_plane = 0.1f;
constexpr float global_far_plane = 500.0f;

enum FixDirection
{
    X,
    Y,
    D1,
    D2,
};

enum ProjectionType
{
    Orthogonal,
    Perspective
};

class ViewCamera
{
public:
    ViewCamera();

    void setMouseLockedStatus(bool locked);
    void setSensitivity(float mouse_sensitivity);
    void setFOV(float fov);
    void setOrthogonal(float left, float right, float bottom, float top, float near = 0.1f, float far = 100.0f);
    void setPerspective(float aspect, float nearPlane, float farPlane);
    void setPerspective(float left, float right, float bottom, float top, float near = 0.1f, float far = 100.0f);
    void lookAt(const QVector3D &eye, const QVector3D &center, const QVector3D &up);

    void surroundOriginByMouseInput(const QPoint &mouseDelta);
    void surroundOriginThroughFixDirection(FixDirection fixDirection, float angle);

    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mouseReleaseEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);

    QVector3D getEye() const;
    QVector3D getCenter() const;
    QVector3D getUp() const;
    QMatrix4x4 getViewMatrix() const;
    QMatrix4x4 getProjectionMatrix() const;
    float getNearPlaneDistance() const;
    float getFarPlaneDistance() const;
    float getFOV() const;

private:
    QVector3D m_eye;
    QVector3D m_center;
    QVector3D m_up;

    QMatrix4x4 m_view;
    QMatrix4x4 m_projection;

    float m_yaw;
    float m_pitch;
    float m_fov;
    float m_near;
    float m_far;

    bool m_mouseLocked;
    float m_sensitivity = 0.1f;
};

#endif // VIEWCAMERA_H
